package com.xzcs.service.weixin;

import com.xzcs.mapper.weixin.WxMenuMapper;
import com.xzcs.mapper.weixin.WxReceiveMsgMapper;
import com.xzcs.mapper.weixin.WxUserMapper;
import com.xzcs.service.weixin.expand.ExpandService;
import com.xzcs.util.common.StringUtils;
import com.xzcs.util.web.RequestUtils;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.builder.outxml.NewsBuilder;
import me.chanjar.weixin.mp.util.xml.XStreamTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WechatService extends WxBaseService {

	@Autowired
	public WxReceiveMsgMapper wxReceiveMsgMapper;
	@Autowired
	public WxUserMapper wxUserMapper;
	@Autowired
	public WxMenuMapper wxMenuMapper;

	public String coreService(HttpServletRequest request) {
		String acctId = RequestUtils.getValue(request, "acctId");
		String responseMsg = "";
		try {
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
			String inMsg = XStreamTransformer.toXml(WxMpXmlMessage.class, inMessage);
			String msgType = inMessage.getMsgType();
			if (msgType.equals(WxConsts.XML_MSG_TEXT)) {//文本
				responseMsg = dealTextMsg(request, acctId, inMessage);
			} else if (msgType.equals(WxConsts.XML_MSG_IMAGE)) {//图片

			} else if (msgType.equals(WxConsts.XML_MSG_VOICE)) {//语音

			} else if (msgType.equals(WxConsts.XML_MSG_VIDEO)) {//视频

			} else if (msgType.equals(WxConsts.XML_MSG_SHORTVIDEO)) {//小视频

			} else if (msgType.equals(WxConsts.XML_MSG_NEWS)) {

			} else if (msgType.equals(WxConsts.XML_MSG_MUSIC)) {

			}  else if (msgType.equals(WxConsts.XML_MSG_LOCATION)) {//地理位置

			} else if (msgType.equals(WxConsts.XML_MSG_LINK)) {//链接

			} else if (msgType.equals(WxConsts.XML_MSG_EVENT)) {//事件
				String event = inMessage.getEvent();
				if (event.equals(WxConsts.EVT_SUBSCRIBE)) {//关注
					responseMsg = dealSubscribeEvent(request, acctId, inMessage);
				} else if (event.equals(WxConsts.EVT_UNSUBSCRIBE)) {//取消关注，用户收不到消息，不用回复消息只要将用户在用户表中删除
					dealUnSubscribeEvent(request, acctId, inMessage);
				} else if (event.equals(WxConsts.EVT_SCAN)) {//扫描
					logger.debug(inMessage.getFromUser()+"扫描:"+inMessage.getTicket());
				} else if (event.equals(WxConsts.EVT_LOCATION)) {//上报地理位置
					logger.debug(inMessage.getFromUser()+"上报位置:"+inMessage.getLongitude());
				} else if (event.equals(WxConsts.EVT_CLICK)) {//点击菜单
					responseMsg = dealClickEvent(request, acctId, inMessage);
				} else if (event.equals(WxConsts.EVT_VIEW)) {//点击链接
					logger.debug(inMessage.getFromUser()+"点击链接:"+inMessage.getEventKey());
				} else {
					logger.debug(inMessage.getFromUser()+"事件类型:"+event);
				}
			} else {
				logger.debug(inMessage.getFromUser()+"消息类型:"+msgType);
			}

			Map<String, Object> params = new HashMap<String, Object>();
			params.put("id", StringUtils.getUUID());
			params.put("fromUser", inMessage.getFromUser());
			params.put("toUser", inMessage.getToUser());
			params.put("inMessage", inMsg);
			params.put("outMessage", responseMsg);
			params.put("accountId", acctId);
			wxReceiveMsgMapper.insertReceive(params);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return responseMsg;
	}

	public Map<String, Object> findAutoResponse(String accountId, String content){
		List<Map<String, Object>> list = wxResponseMapper.findAutoResponses(accountId);
		for (Map<String, Object> map : list) {
			String reqKey = StringUtils.get(map, "req_key");
			if (content.contains(reqKey) || content.startsWith(reqKey)){
				return map;
			}
		}
		return null;
	}

	public Map<String, Object> findTextResponse(String templateId){
		return wxResponseMapper.findTextResponse(templateId);
	}

	public List<Map<String, Object>> findNewsResponse(String templateId){
		return wxResponseMapper.findNewsResponse(templateId);
	}

	public Map<String, Object> findExpand(String templateId){
		return wxResponseMapper.findExpand(templateId);
	}

	public Map<String, Object> findSubsResponse(String accountId){
		return wxResponseMapper.findSubsResponse(accountId);
	}

	public Map<String, Object> findEventResponse(String accountId, String eventKey){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("accountId", accountId);
		List<Map<String, Object>> menus = wxMenuMapper.findMenus(params);
		for (Map<String, Object> map : menus) {
			String menuKey = StringUtils.get(map, "menu_key");
			if (eventKey.equals(menuKey)){
				return map;
			}
		}
		return wxResponseMapper.findSubsResponse(accountId);
	}

	public String dealTextMsg(HttpServletRequest request, String accountId, WxMpXmlMessage inMessage){
		String responseMsg = "";
		String content = inMessage.getContent();
		Map<String, Object> autoResp = findAutoResponse(accountId, content);
		if (null != autoResp) {
			String msgType = StringUtils.get(autoResp, "msg_type");
			String templateId = StringUtils.get(autoResp, "template_id");
			responseMsg = getResponseMsg(request, msgType, templateId, inMessage);
		} else {
			WxMpXmlOutMessage outMessage = getOutTextMsg("机器人找不到【"+inMessage.getContent()+
					"】的相关信息，请试试其他关键字。", inMessage);
			responseMsg = outMessage.toXml();
		}
		return responseMsg;
	}

	public String getResponseMsg(HttpServletRequest request, String msgType, String templateId, WxMpXmlMessage inMessage){
		String imgSite = propertyUtils.getPropertyValue("xzcs.images.site");
		String responseMsg = "";
		if (msgType.equals("text")){
			Map<String, Object> txtResp = findTextResponse(templateId);
			WxMpXmlOutMessage outMessage = getOutTextMsg(StringUtils.get(txtResp, "content"), inMessage);
			responseMsg = outMessage.toXml();
		} else if (msgType.equals("news")) {
			List<Map<String, Object>> newsResp = findNewsResponse(templateId);
			NewsBuilder newsBuilder = WxMpXmlOutMessage.NEWS()
					.fromUser(inMessage.getToUser())
					.toUser(inMessage.getFromUser());
			for (Map<String, Object> map : newsResp) {
				WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
				item.setUrl(StringUtils.get(map, "url"));
				item.setPicUrl(imgSite + StringUtils.get(map, "image_url"));
				item.setDescription(StringUtils.get(map, "description"));
				item.setTitle(StringUtils.get(map, "title"));
				newsBuilder.addArticle(item);

			}
			WxMpXmlOutNewsMessage outMessage = newsBuilder.build();
			responseMsg = outMessage.toXml();
		} else if (msgType.equals("expand")) {
			Map<String, Object> expandResp = findExpand(templateId);
			String className = StringUtils.get(expandResp, "class_name");
			try {
				ExpandService expandService = (ExpandService) Class.forName(className).newInstance();
				responseMsg = expandService.excute(request, inMessage);
			} catch (Exception e) {
				logger.error("微信扩展功能调用错误：", e);
				WxMpXmlOutMessage outMessage = getOutTextMsg("暂不支持，我们会尽快完善，感谢您的支持。", inMessage);
				responseMsg = outMessage.toXml();
			}
		} else {
			WxMpXmlOutMessage outMessage = getOutTextMsg("暂不支持，我们会尽快完善，感谢您的支持。", inMessage);
			responseMsg = outMessage.toXml();
		}
		return responseMsg;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public String dealSubscribeEvent(HttpServletRequest request, String accountId, WxMpXmlMessage inMessage){
		String responseMsg = "谢谢您的关注，感谢您的支持！";
		Map<String, Object> subsResp = findSubsResponse(accountId);
		if (null != subsResp) {
			String msgType = StringUtils.get(subsResp, "msg_type");
			String templateId = StringUtils.get(subsResp, "template_id");
			responseMsg = getResponseMsg(request, msgType, templateId, inMessage);
		} else {
			WxMpXmlOutMessage outMessage = getOutTextMsg("谢谢您的关注，感谢您的支持。", inMessage);
			responseMsg = outMessage.toXml();
		}
		//这里将订阅用户保存到用户表中
		wxUserMapper.deleteWxUser(inMessage.getFromUser(), accountId);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", StringUtils.getUUID());
		params.put("openId", inMessage.getFromUser());
		params.put("accountId", accountId);
		wxUserMapper.insertWxUser(params);
		return responseMsg;
	}

	public void dealUnSubscribeEvent(HttpServletRequest request, String accountId, WxMpXmlMessage inMessage){
		//这里删除订阅用户
		wxUserMapper.deleteWxUser(inMessage.getFromUser(), accountId);
	}

	public String dealClickEvent(HttpServletRequest request, String accountId, WxMpXmlMessage inMessage){
		String responseMsg = "暂不支持，我们会尽快完善，感谢您的支持！";
		Map<String, Object> eventResp = findEventResponse(accountId, inMessage.getEventKey());
		if (null != eventResp) {
			String msgType = StringUtils.get(eventResp, "msg_type");
			String templateId = StringUtils.get(eventResp, "template_id");
			responseMsg = getResponseMsg(request, msgType, templateId, inMessage);
		} else {
			WxMpXmlOutMessage outMessage = getOutTextMsg("暂不支持，我们会尽快完善，感谢您的支持。", inMessage);
			responseMsg = outMessage.toXml();
		}
		return responseMsg;
	}
}
